package com.stu.manager.studentscoremanagersys.interceptor;

import com.stu.manager.studentscoremanagersys.enums.CodeEnum;
import com.stu.manager.studentscoremanagersys.exception.BIZexception;
import com.stu.manager.studentscoremanagersys.res.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.yaml.snakeyaml.constructor.DuplicateKeyException;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestControllerAdvice
public class EXAdvice {




    /**
     * 处理参数校验不通过异常
     * 处理条件： 普通的通过对象格式提交过来参数，
     * 提交格式Content-Type：x-wwww-form-urlcode + @RequestBody 提交参数时
     * @param ex
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    public Result<String> handleException(BindException ex){
        log.info("入参校验失败{}");
        List<FieldError> fieldErrors = ex.getFieldErrors();
        return Result.buildFailure(appendStringSlice(fieldErrors));
    }



    /**
     * 处理参数校验不通过异常
     * 处理条件： 提交格式Content-Type：application/json+ @RequestBody 提交参数时
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result<String> handleException(MethodArgumentNotValidException ex){
        log.info("入参校验失败{}");
        BindingResult buildResult = ex.getBindingResult();
        List<FieldError> fieldErrors = buildResult.getFieldErrors();

        return Result.buildFailure(appendStringSlice(fieldErrors));
    }


    /**
     * 拼接字符串方法
     * @param fieldErrors
     * @return
     */
    private String appendStringSlice(List<FieldError> fieldErrors ){
        String errorMsg= fieldErrors.stream().map(fieldError->{
            StringBuilder sb = new StringBuilder();
            sb.append("属性：").append(fieldError.getField())
                    .append("，得到的属性值：").append(fieldError.getRejectedValue())
                    .append(",校验不通过原因是：").append(fieldError.getDefaultMessage());
            return sb.toString();
        }).collect(Collectors.joining(";"));
        return errorMsg;
    }

    /**
     * 参数不合法校验
     * @param ex
     * @return
     */
    @ExceptionHandler(value = IllegalArgumentException.class)
    public Result<String> handleException(IllegalArgumentException ex){
        log.info("参数不合法{}");
        return Result.buildFailure(CodeEnum.PARA_ERROR);
    }

    /**
     * 数据库不合法校验
     * @param ex
     * @return
     */
    @ExceptionHandler(value = BadSqlGrammarException.class)
    public Result<String> handleException(BadSqlGrammarException ex){
        log.info("数据库不合法校验{}");
        return Result.buildFailure(CodeEnum.DB_ERROR);
    }

    /**
     * 数据库违反唯一性约束
     * @param ex
     * @return
     */
    @ExceptionHandler(value = DuplicateKeyException.class)
    public Result<String> handleException(DuplicateKeyException ex){
        log.info("数据库违反唯一性约束{}");
        return Result.buildFailure(CodeEnum.DUPLIT_KEY_ERROR);
    }

    /**
     * 业务异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = BIZexception.class)
    public Result<String> handleException(BIZexception ex){
        log.info("数据库违反唯一性约束{}");
        return Result.buildFailure(ex.getCode(),ex.getMessage());
    }


    /**
     * 没有精准匹配的异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Result<String> handleException(Exception ex){
        log.info("没有精准匹配的异常{}");
        return Result.buildFailure(CodeEnum.SYS_ERROR);
    }

    /**
     * 请求方式异常，get，post
     * @param ex
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public Result<String> handleException(HttpRequestMethodNotSupportedException ex){
        log.info("请求方式异常{}");
        return Result.buildFailure(CodeEnum.REQUEST_ERROR);
    }


}
